# -*- coding: utf-8; -*-

"""Code for the preferences dialog of Siocwave."""

import locale

import wx

import config
import meta


class PreferencesDialog(wx.Dialog):
    """The preferences dialog."""
    def __init__(self, parent, config_mgr):
        wx.Dialog.__init__(self, parent, id=-1, title=u'Siocwave Preferences')
        
        vbox = wx.BoxSizer(wx.VERTICAL)
        
        cache_frame = wx.StaticBox(self, label=u'HTTP caching')
        cache_vbox = wx.StaticBoxSizer(cache_frame, wx.VERTICAL)
        
        current_cache = config_mgr.get_cache()
        
        self.cache_ckbox = wx.CheckBox(self, label=u'Enable HTTP caching')
        self.cache_ckbox.SetValue(current_cache is not None)
        self.cache_loc_label = wx.StaticText(self, label=u'Cache directory:')
        self.cache_loc_label.Enable(current_cache is not None)
        self.cache_loc = wx.TextCtrl(self)
        if current_cache is None:
            self.cache_loc.SetValue(config.guess_cache_dir())
        else:
            self.cache_loc.SetValue(current_cache)
        self.cache_loc.Enable(current_cache is not None)
        self.cache_loc.SetMinSize((400, self.cache_loc.GetMinHeight()))
        
        cache_vbox.Add(self.cache_ckbox, flag=wx.ALL, border=10)
        cache_vbox.Add(self.cache_loc_label,
                       flag=(wx.LEFT | wx.RIGHT | wx.BOTTOM), border=10)
        cache_vbox.Add(self.cache_loc,
                       flag=(wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM),
                       border=10)
        
        infer_frame = wx.StaticBox(self, label=u'Inference')
        infer_vbox = wx.StaticBoxSizer(infer_frame, wx.VERTICAL)
        
        rdfs_auto_infer = config_mgr.get_rdfs_auto_infer()
        
        self.infer_ckbox = wx.CheckBox(self,
            label=u'Enable automatic RDFS inference')
        self.infer_ckbox.SetValue(rdfs_auto_infer)
        self.preload_label = wx.StaticText(self,
            label=u'Preload vocabularies (on startup and on Data -> Clear):')
        self.preload_label.Enable(rdfs_auto_infer)
        
        preload_panel = wx.Panel(self)
        preload_hbox = wx.BoxSizer(wx.HORIZONTAL)
        if rdfs_auto_infer:
            preload = config_mgr.get_preload()
        else:
            # Default preload URLs (for showing in list) are SIOC vocabularies
            preload = [
                u'http://rdfs.org/sioc/ns',
                u'http://rdfs.org/sioc/types'
            ]
        self.preload_list = wx.ListBox(preload_panel, choices=preload)
        self.preload_list.Enable(rdfs_auto_infer)
        
        preload_btn_panel = wx.Panel(preload_panel)
        preload_btn_vbox = wx.BoxSizer(wx.VERTICAL)
        self.preload_add_btn = wx.Button(preload_btn_panel, wx.ID_ADD)
        self.preload_add_btn.Enable(rdfs_auto_infer)
        self.preload_edit_btn = wx.Button(preload_btn_panel, wx.ID_EDIT)
        self.preload_edit_btn.Enable(rdfs_auto_infer)
        self.preload_delete_btn = wx.Button(preload_btn_panel, wx.ID_DELETE)
        self.preload_delete_btn.Enable(rdfs_auto_infer)
        preload_btn_vbox.Add(self.preload_add_btn,
                             flag=(wx.LEFT | wx.BOTTOM), border=10)
        preload_btn_vbox.Add(self.preload_edit_btn,
                             flag=(wx.LEFT | wx.BOTTOM), border=10)
        preload_btn_vbox.Add(self.preload_delete_btn, flag=wx.LEFT, border=10)
        preload_btn_panel.SetSizer(preload_btn_vbox)
        
        preload_hbox.Add(self.preload_list, flag=wx.EXPAND, proportion=1)
        preload_hbox.Add(preload_btn_panel)
        preload_panel.SetSizer(preload_hbox)
        
        infer_vbox.Add(self.infer_ckbox, flag=wx.ALL, border=10)
        infer_vbox.Add(self.preload_label,
                       flag=(wx.LEFT | wx.RIGHT | wx.BOTTOM), border=10)
        infer_vbox.Add(preload_panel,
                       flag=(wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND),
                       border=10)
        
        btn_panel = wx.Panel(self)
        btn_hbox = wx.BoxSizer(wx.HORIZONTAL)
        ok = wx.Button(btn_panel, id=wx.ID_OK)
        ok.SetDefault()
        cancel = wx.Button(btn_panel, id=wx.ID_CANCEL)
        btn_hbox.Add(ok, flag=(wx.ALIGN_RIGHT | wx.RIGHT), border=5)
        btn_hbox.Add(cancel, flag=wx.ALIGN_RIGHT, border=5)
        btn_panel.SetSizer(btn_hbox)
        
        vbox.Add(cache_vbox, flag=(wx.ALL | wx.EXPAND), border=15)
        vbox.Add(infer_vbox, flag=(wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND),
                 border=15)
        vbox.Add(btn_panel,
                 flag=(wx.ALIGN_RIGHT | wx.LEFT | wx.RIGHT | wx.BOTTOM),
                 border=15)
        self.SetSizer(vbox)
        vbox.SetSizeHints(self)
        
        self.cache_ckbox.Bind(wx.EVT_CHECKBOX, self.on_toggle_cache)
        self.infer_ckbox.Bind(wx.EVT_CHECKBOX, self.on_toggle_infer)
        self.preload_add_btn.Bind(wx.EVT_BUTTON, self.on_invoke_add)
        self.preload_edit_btn.Bind(wx.EVT_BUTTON, self.on_invoke_edit)
        self.preload_delete_btn.Bind(wx.EVT_BUTTON, self.on_invoke_delete)
        ok.Bind(wx.EVT_BUTTON, self.on_ok)
        
        self.config_mgr = config_mgr
        
        self.Centre()
        self.Show()
    
    def on_toggle_cache(self, event):
        self.cache_loc_label.Enable(self.cache_ckbox.GetValue())
        self.cache_loc.Enable(self.cache_ckbox.GetValue())
    
    def on_toggle_infer(self, event):
        val = self.infer_ckbox.GetValue()
        self.preload_label.Enable(val)
        self.preload_list.Enable(val)
        self.preload_add_btn.Enable(val)
        self.preload_edit_btn.Enable(val)
        self.preload_delete_btn.Enable(val)
    
    def on_invoke_add(self, event):
        dlg = wx.TextEntryDialog(self, message=u'URL of the resource to load:',
                                 caption=u'Add vocabulary for preloading',
                                 defaultValue=u'')
        dlg.ShowModal()
        url = dlg.GetValue()
        if (url != u'') and not (url in self.preload_list.GetStrings()):
            if not meta.is_ascii(url):
                meta.show_ascii_error(self)
            else:
                self.preload_list.Append(url)
    
    def on_invoke_edit(self, event):
        old = unicode(self.preload_list.GetStringSelection())
        if old != u'':
            dlg = wx.TextEntryDialog(self,
                message=u'URL of the resource to load:',
                caption=u'Add vocabulary for preloading',
                defaultValue=old)
            dlg.ShowModal()
            new = dlg.GetValue()
            if new != u'':
                if not meta.is_ascii(new):
                    meta.show_ascii_error(self)
                else:
                    self.preload_list.SetString(
                        self.preload_list.GetSelection(), new)
    
    def on_invoke_delete(self, event):
        sel = self.preload_list.GetSelection()
        if sel != wx.NOT_FOUND:
            self.preload_list.Delete(sel)
    
    def on_ok(self, event):
        if self.cache_ckbox.GetValue():
            self.config_mgr.set_cache(self.cache_loc.GetValue().encode(
                locale.getpreferredencoding()))
        else:
            self.config_mgr.set_cache(None)
        
        self.config_mgr.set_rdfs_auto_infer(self.infer_ckbox.GetValue())
        if self.infer_ckbox.GetValue():
            self.config_mgr.set_preload(
                [unicode(url) for url in self.preload_list.GetStrings()]
            )
        else:
            self.config_mgr.set_preload([])
        
        self.config_mgr.save()
        self.Close()
